package com.irs.irsforum.security.access;

import com.irs.irsforum.entity.Student;
import com.irs.irsforum.entity.User;
import com.irs.irsforum.exception.IIrsForumException;
import com.irs.irsforum.exception.impl.IrsForumExceptionImpl;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

/**
 * @author yihuili
 *
 * @since 2020-01-18
 *
 */
@Aspect
@Component
public class AccessAspect {

    private static final Logger logger =
            LoggerFactory.getLogger(AccessAspect.class);


    @Before(value="execution(* com.irs.irsforum.web.*.*(..))" +
            "&& @annotation(access)")
    public void checkAccess(JoinPoint jp, Access access)  {
        logger.debug("Check request access," + jp.getSignature().getName());

        UserType userType = this.getUserType();
        UserType[] userTypes = access.userType();
        if (userTypes.length == 0) {
            throw new IrsForumExceptionImpl("not allowd access.",
                    IIrsForumException.IrsForumExceptionType.NOT_AUTHORIZED);
        }
        for (UserType type : userTypes) {
            if (userType.equals(type)) {
                return;
            }
        }

        throw new IrsForumExceptionImpl("user not login.",
                IIrsForumException.IrsForumExceptionType.USER_NOT_LOGIN);
    }

    protected User getUser() {
        return (User) SecurityContextHolder.getContext()
                .getAuthentication();
    }

    protected boolean isLoginUser() {
        User user = getUser();
        if(user != null && user.getId() == -1L){
            throw new IrsForumExceptionImpl("Illegal login (Too long login interval).",
                    IIrsForumException.IrsForumExceptionType.ILLEGAL_LOGIN);
        }
        if (user == null || !user.isAuthenticated() || user.getId() == 0L) {
            return false;
        }
        return true;
    }


    private UserType getUserType() {
        if (isLoginUser()) {
            return UserType.LOGIN_USER;
        }
        return UserType.UNLOGIN_USER;
    }
}
